﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Cqrs.Infrastructure
{
    public interface ICommandSender
    {
        void Send(Command command);
    }

    public class CommandBus : ICommandSender
    {
        private readonly Dictionary<Type, List<Action<Command>>> _commands = new Dictionary<Type, List<Action<Command>>>();

        public void RegisterHandler<T>(Action<T> handler) where T : Command
        {
            List<Action<Command>> handlers;
            if (!_commands.TryGetValue(typeof(T), out handlers))
            {
                handlers = new List<Action<Command>>();
                _commands.Add(typeof(T), handlers);
            }
            handlers.Add(DelegateAdjuster.CastArgument<Command, T>(x => handler(x)));
        }

        public void Send(Command command)
        {
            List<Action<Command>> handlers;
            if (_commands.TryGetValue(command.GetType(), out handlers))
            {
                if (handlers.Count != 1) throw new InvalidOperationException("cannot send to more than one handler");
                handlers[0](command);
            }
            else
            {
                throw new InvalidOperationException("no handler registered");
            }
        }
    }
}
